import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:zhibao_flutter/util/check/regular.dart';
import 'package:zhibao_flutter/util/func/log.dart';
import 'package:zhibao_flutter/util/ui/my_toast.dart';

import 'base_response_model.dart';

export 'base_response_model.dart';

typedef ResponseCall = Function(int code, String msg);

class BaseViewModel {
  int id = 0;

  var dataController = StreamController<dynamic>.broadcast();

  Sink get inDataController => dataController;

  List dataList = [];
  var datas;

  Stream<dynamic> get stream => dataController.stream.map((data) {
        dataList.addAll(data);
        return dataList;
      });

  dynamic getData() => null;

  refreshData() {}

  loadMoreData() {}

  dispose() {
    dataController.close();
  }

  void dataModelFromJson(data, model, [dataController]) {
    List repData = data['Data'];

    assert(repData is List);

    List? list = [];

    for (var json in repData) {
      list.add(model.from(json));
    }

    inDataController.add(list);
  }

  List<T> dataModelListFromJson<T>(data, model, [dataController]) {
    return runZoned(
      () {
        List? repData = data;

        if (repData == null) {
          return [];
        }

        assert(repData is List);

        List<T> list = [];

        for (var json in repData) {
          list.add(model.from(json));
        }

        return list;
      },
      onError: (Object error, StackTrace stackTrace) {
        var _stackTrace = stackTrace.toString();
        var _indexStart = _stackTrace.indexOf('(');
        var _indexEnd = _stackTrace.indexOf(')');
        var _result = _stackTrace.substring(_indexStart, _indexEnd + 1);

        id++;

        throw ResponseModel.fromError(
            'HANDLE_ERROR_ROW::[$id]::$_result,${error.toString()}', id);
      },
    );
  }

  List<T> dataModelListFromJsonCall<T>(
      data, Function(Map<String, dynamic> json) modelCall,
      [dataController]) {
    return runZoned(
      () {
        List repData;
        if (data is Map) {
          repData = data['pageData'];
        } else if (data is List) {
          repData = data;
        } else {
          repData = [];
        }

        if (repData == null) {
          return [];
        }

        assert(repData is List);

        List<T> list = [];

        for (var json in repData) {
          list.add(modelCall(json));
        }

        return list;
      },
      onError: (Object error, StackTrace stackTrace) {
        var _stackTrace = stackTrace.toString();
        var _indexStart = _stackTrace.indexOf('(');
        var _indexEnd = _stackTrace.indexOf(')');
        var _result = _stackTrace.substring(_indexStart, _indexEnd + 1);

        id++;

        throw ResponseModel.fromError(
            'HANDLE_ERROR_ROW::[$id]::$_result,${error.toString()}', id);
      },
    );
  }

  Future<ResponseModel> throwError(e) {
    if (e is TypeError || e is NoSuchMethodError || e is! ResponseModel) {
      throw ResponseModel.fromError('${e?.toString()}', 0);
    }
    throw ResponseModel.fromError(e.message ?? '', e.code, e.apiName ?? 'e');
  }

  void handlePhone(phone) {
    String _phone = '$phone';
    if (!strNoEmpty(_phone)) {
      throw ResponseModel.fromParamError('请输入手机号/邮箱');
    // } else if (!isMobilePhoneNumber(_phone)) {
    //   throw ResponseModel.fromParamError('请输入正确的手机号/邮箱');
    }
  }

  void handleNull(List data) {
    data.map((e) {
      bool strIsNull = e is String && !strNoEmpty(e);
      if (strIsNull || e == null) {
        throw ResponseModel.fromParamError('参数不能为空');
      }
    });
  }
}

Future<ResponseModel> onError(
  dynamic e,
  StackTrace? stackTrace, {
  bool isTop = false,
  bool showToast = true,
}) async {
  LogUtil.d(
      "When call api :: onError :: type[${e.runtimeType}] :: ${e.toString()}, the e?.code is ${e?.code}");
  if (e == null || !strNoEmpty(e?.toString())) {
    debugPrint('e====>出现空提示');
    return ResponseModel();
  }
  if (e is TypeError || e is NoSuchMethodError) {
    // if (kDebugMode) myToast(page: currentPage, msg: "unknown error");
    debugPrint('e====>${e?.toString()}');
  } else if (e?.code == 2 || e?.code == '2') {
    debugPrint('e====>错误为2不提示');
    return ResponseModel();
  } else if (e?.code == 300102 || e?.code == '300102') {
    debugPrint('e====>错误为300102不提示');
    return ResponseModel();
  } else {
    var _msg = '${e?.message}';
    if (_msg.contains('维护')) {
      return ResponseModel();
    }
    if (_msg.contains('subtype') || _msg.contains('null')) {
      // if (kDebugMode) myToast(page: currentPage, msg: "unknown error");
      debugPrint("e====>$_msg");
      myToast("未知错误");
    } else if (_msg.contains('HANDLE_ERROR_ROW')) {
      var _in = _msg.split(',');
      debugPrint("${_in[0]}");
      debugPrint("HANDLE_ERROR_ROW::[${e.code}]::${_in[1]}");
      // myToast(
      //   page: currentPage,
      //   msg: "类型解析错误，请联系客服处理",
      // );
    } else if (_msg.contains('账号不存在或被删除')) {
      debugPrint("e====>${e?.message}，【清除登录数据】");
    } else {
      debugPrint("e====>${e?.message}");
      bool isDioError = _msg.contains('https') && _msg.contains('（');
      var resultMsg = isDioError
          ? _msg.substring(0, _msg.indexOf('（')).replaceAll('"', '')
          : _msg;

      if (resultMsg == "The user did not allow camera access.") {
        if (showToast) {
          myToast("权限被拒绝");
        } else {
          LogUtil.d("myToast::权限被拒绝");
        }
      } else {
        if (showToast) {
          myToast(resultMsg);
        } else {
          LogUtil.d("myToast::$resultMsg");
        }
      }
    }
  }
  return ResponseModel();
}
